package com.gs.api.projects.weixin.web;

import cn.hutool.core.bean.BeanUtil;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.gs.api.projects.weixin.entity.LoginRequest;
import com.gs.api.projects.weixin.entity.WxUser;
import com.gs.api.projects.weixin.service.WxUserService;
import com.gs.api.config.weixin.WxMaConfiguration;
import com.gs.api.core.Result;
import com.gs.api.projects.weixin.vo.LoginResult;
import com.gs.api.util.JsonUtils;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiImplicitParam;
import io.swagger.annotations.ApiImplicitParams;
import io.swagger.annotations.ApiOperation;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;

import cn.binarywang.wx.miniapp.api.WxMaService;
import cn.binarywang.wx.miniapp.bean.WxMaJscode2SessionResult;
import cn.binarywang.wx.miniapp.bean.WxMaPhoneNumberInfo;
import cn.binarywang.wx.miniapp.bean.WxMaUserInfo;
import me.chanjar.weixin.common.error.WxErrorException;

import java.util.Date;

/**
 * @author guoyunfei on 2021/7/10 16:19
 * @className WxMaUserController
 * @description TODO 微信小程序用户接口
 * @Version 1.0
 */
@Api(tags = "微信小程序登录")
@RestController
@RequestMapping("{appid}/wx")
public class WxLoginController {
    private final Logger logger = LoggerFactory.getLogger(this.getClass());


    @Autowired
    private WxUserService wxUserService;

    /**
     * 登陆接口
     */
    @ApiOperation(value = "微信用户登录", notes="微信用户登录")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "appid", value = "微信appid", required = true, dataType = "String"),
    })
    @GetMapping("/login")
    public Result login(@PathVariable String appid, LoginRequest loginRequest,WxUser wxUser) {
        if (StringUtils.isBlank(loginRequest.getCode())) {
            return Result.failure("empty jscode");
        }

        final WxMaService wxService = WxMaConfiguration.getMaService(appid);

        try {
            WxMaJscode2SessionResult session = wxService.getUserService().getSessionInfo(loginRequest.getCode());
            this.logger.info(session.getSessionKey());
            this.logger.info(session.getOpenid());
            this.logger.info(session.getUnionid());
            //TODO 关联业务相关数据

            wxUser.setOpenid(session.getOpenid());
            wxUser.setAppid(appid);

            QueryWrapper<WxUser> queryWrapper = new QueryWrapper<>();
            queryWrapper.eq("appid",appid);
            queryWrapper.eq("openid",session.getOpenid());

            WxUser user = wxUserService.getOne(queryWrapper);
            wxUser.setUnionid(session.getUnionid());

            LoginResult lr = new LoginResult();

            if(null == user){
                wxUserService.insert(wxUser);
                lr.setNewUser(true);
            }else {
                wxUser.setLastLoginTime(new Date());
                wxUserService.update(wxUser);
            }
            BeanUtil.copyProperties(session,lr);
            return Result.success(lr);
        } catch (WxErrorException e) {
            this.logger.error(e.getMessage(), e);
            return Result.failure(e.getMessage());
        }
    }

    /**
     * <pre>
     * 获取用户信息接口
     * </pre>
     */
    @ApiOperation(value = "获取用户信息接口", notes="获取用户信息接口")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "appid", value = "微信appid", required = true, dataType = "String"),
            @ApiImplicitParam(name = "sessionKey", value = "sessionKey", required = true, dataType = "String"),
            @ApiImplicitParam(name = "signature", value = "signature", required = true, dataType = "String"),
            @ApiImplicitParam(name = "rawData", value = "rawData", required = true, dataType = "String"),
            @ApiImplicitParam(name = "encryptedData", value = "encryptedData", required = true, dataType = "String"),
            @ApiImplicitParam(name = "iv", value = "iv", required = true, dataType = "String"),
    })
    @GetMapping("/info")
    public String info(@PathVariable String appid, String sessionKey,
                       String signature, String rawData, String encryptedData, String iv) {
        final WxMaService wxService = WxMaConfiguration.getMaService(appid);

        // 用户信息校验
        if (!wxService.getUserService().checkUserInfo(sessionKey, rawData, signature)) {
            return "user check failed";
        }

        // 解密用户信息
        WxMaUserInfo userInfo = wxService.getUserService().getUserInfo(sessionKey, encryptedData, iv);

        return JsonUtils.toJson(userInfo);
    }

    /**
     * <pre>
     * 获取用户绑定手机号信息
     * </pre>
     */
    @ApiOperation(value = "获取用户绑定手机号信息", notes="获取用户绑定手机号信息")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "appid", value = "微信appid", required = true, dataType = "String"),
            @ApiImplicitParam(name = "sessionKey", value = "sessionKey", required = true, dataType = "String"),
            @ApiImplicitParam(name = "signature", value = "signature", required = true, dataType = "String"),
            @ApiImplicitParam(name = "rawData", value = "rawData", required = true, dataType = "String"),
            @ApiImplicitParam(name = "encryptedData", value = "encryptedData", required = true, dataType = "String"),
            @ApiImplicitParam(name = "iv", value = "iv", required = true, dataType = "String"),
    })
    @GetMapping("/phone")
    public String phone(@PathVariable String appid, String sessionKey, String signature,
                        String rawData, String encryptedData, String iv) {
        final WxMaService wxService = WxMaConfiguration.getMaService(appid);

        // 用户信息校验
        if (!wxService.getUserService().checkUserInfo(sessionKey, rawData, signature)) {
            return "user check failed";
        }

        // 解密
        WxMaPhoneNumberInfo phoneNoInfo = wxService.getUserService().getPhoneNoInfo(sessionKey, encryptedData, iv);

        return JsonUtils.toJson(phoneNoInfo);
    }

}
